﻿#include <cstdio>

#include "socketlibfunction.h"
#include "selectpoll.h"
#include "socketfd.h"

SocketLib::SelectPoll::SelectPoll()
{
    m_readSet = &(m_socketSet.getReadFDSet());
}

void SocketLib::SelectPoll::doPoll(long    aTimeout)
{
    int activenum = m_socketSet.poll(aTimeout);
    if (activenum > 0)
    {

        #if defined PLATFORM_WINDOWS
        ACTIVELIST::iterator iter;
        for( int i = 0; i < (int)m_readSet->fd_count; ++i )
        {
            iter = m_socketFdList.find(m_readSet->fd_array[i]);
            SocketFD*    currentfd = (*iter).second;

            if (!onSockedFDRecv(currentfd))
            {
                m_socketFdList.erase(iter);
                m_socketSet.delSock(currentfd->getSocketFD());

                currentfd->onClose();
                SocketLib::SocketApi::CloseSocket(currentfd->getSocketFD());
            }
        }
        #else
        ACTIVELIST::iterator it = m_socketFdList.begin();
        for (; it != m_socketFdList.end(); )
        {
            SocketFD*    currentfd = (*it).second;

            if (onSockedFDRecv(currentfd))
            {
                ++it;
            }
            else
            {
                m_socketFdList.erase(it++);
                m_socketSet.delSock(currentfd->getSocketFD());

                SocketApi::CloseSocket(currentfd->getSocketFD());
                currentfd->onClose();
            }
        }
        #endif
    }
    else if(SOCKET_ERROR == activenum)
    {
        if(S_EINTR != sErrno)
        {
            onPollError();
        }
    }
}

void SocketLib::SelectPoll::addSocketFD(SocketFD* pSocketFD)
{
    if (m_socketFdList.find(pSocketFD->getSocketFD()) == m_socketFdList.end())
    {
        m_socketFdList[pSocketFD->getSocketFD()] = pSocketFD;
        m_socketSet.addSock(pSocketFD->getSocketFD());
    }
}
void SocketLib::SelectPoll::delSocketFD(SocketFD* pSocketFD)
{
    m_socketFdList.erase(pSocketFD->getSocketFD());
    m_socketSet.delSock(pSocketFD->getSocketFD());
}

void SocketLib::SelectPoll::onPollError()
{

}

bool SocketLib::SelectPoll::onSockedFDRecv(SocketFD* pSocketFD)
{
    do
    {
        if (! pSocketFD->isValid())
        {
            break;
        }

        if (m_socketSet.isActive(pSocketFD->getSocketFD(), SocketSet::ReadActive))
        {
            if (!pSocketFD->onRead())
            {
                break;
            }
        }
        if (m_socketSet.isActive(pSocketFD->getSocketFD(), SocketSet::WriteActive))
        {
            if (! pSocketFD->onSend())
            {
                break;
            }
        }
        if (m_socketSet.isActive(pSocketFD->getSocketFD(), SocketSet::ErrorActive))
        {
            break;
        }

        return true;
    }while(0);

    return false;
}
